package combo;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Collections.singletonList;
public final class ComboFactory {
public static Combo httpCombo(final URI baseUrl, final RestTemplateVisitor... restTemplateVisitors) {
return new HttpCombo(restTemplate(baseUrl, restTemplateVisitors));
}
private ComboFactory() {
}
private static RestTemplate restTemplate(final URI baseUrl, final RestTemplateVisitor... restTemplateVisitors) {
final RestTemplate restTemplate = new RestTemplate(singletonList(new GsonHttpMessageConverter()));
for (final RestTemplateVisitor visitor : restTemplateVisitors) {
visitor.visit(restTemplate);
}
restTemplate.getInterceptors().add(new BaseUrlInterceptor(baseUrl));
restTemplate.getInterceptors().add(new LoggingInterceptor());
return restTemplate;
}
public interface RestTemplateVisitor {
void visit(final RestTemplate restTemplate);
}
private static final class LoggingInterceptor implements ClientHttpRequestInterceptor {
private final AtomicInteger counter = new AtomicInteger(0);
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
final int current = counter.getAndIncrement();
System.out.printf(" [%s] %s -> %s%n", current, request.getMethod(), request.getURI());
final ClientHttpResponse execute = execution.execute(request, body);
System.out.printf(" [%s] %s%n", current, execute.getStatusCode());
return execute;
}
}
private static final class BaseUrlInterceptor implements ClientHttpRequestInterceptor {
private final URI baseUri;
private BaseUrlInterceptor(final URI baseUri) {
this.baseUri = baseUri;
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
return execution.execute(wrapHttpRequest(request, baseUri), body);
}
private static HttpRequest wrapHttpRequest(final HttpRequest request, final URI baseUri) {
return new HttpRequest() {
@Override public HttpMethod getMethod() {
return request.getMethod();
}
@Override public URI getURI() {
try {
return new URI(baseUri + request.getURI().toString());
} catch (final URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Override public HttpHeaders getHeaders() {
return request.getHeaders();
}
};
}
}
}